home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / lib / ruby / 1.8 / thwait.rb < prev    next >
Encoding:
Ruby Source  |  2010-06-08  |  4.3 KB  |  171 lines

  1. #
  2. #   thwait.rb - thread synchronization class
  3. #       $Release Version: 0.9 $
  4. #       $Revision: 1.3 $
  5. #       $Date: 1998/06/26 03:19:34 $
  6. #       by Keiju ISHITSUKA(Nihpon Rational Software Co.,Ltd.)
  7. #
  8. # --
  9. #  feature:
  10. #  provides synchronization for multiple threads.
  11. #
  12. #  class methods:
  13. #  * ThreadsWait.all_waits(thread1,...)
  14. #    waits until all of specified threads are terminated.
  15. #    if a block is supplied for the method, evaluates it for
  16. #    each thread termination.
  17. #  * th = ThreadsWait.new(thread1,...)
  18. #    creates synchronization object, specifying thread(s) to wait.
  19. #  
  20. #  methods:
  21. #  * th.threads
  22. #    list threads to be synchronized
  23. #  * th.empty?
  24. #    is there any thread to be synchronized.
  25. #  * th.finished?
  26. #    is there already terminated thread.
  27. #  * th.join(thread1,...) 
  28. #    wait for specified thread(s).
  29. #  * th.join_nowait(threa1,...)
  30. #    specifies thread(s) to wait.  non-blocking.
  31. #  * th.next_wait
  32. #    waits until any of specified threads is terminated.
  33. #  * th.all_waits
  34. #    waits until all of specified threads are terminated.
  35. #    if a block is supplied for the method, evaluates it for
  36. #    each thread termination.
  37. #
  38.  
  39. require "thread.rb"
  40. require "e2mmap.rb"
  41.  
  42. #
  43. # This class watches for termination of multiple threads.  Basic functionality
  44. # (wait until specified threads have terminated) can be accessed through the
  45. # class method ThreadsWait::all_waits.  Finer control can be gained using
  46. # instance methods.
  47. #
  48. # Example:
  49. #
  50. #   ThreadsWait.all_wait(thr1, thr2, ...) do |t|
  51. #     STDERR.puts "Thread #{t} has terminated."
  52. #   end
  53. #
  54. class ThreadsWait
  55.   RCS_ID='-$Id: thwait.rb,v 1.3 1998/06/26 03:19:34 keiju Exp keiju $-'
  56.   
  57.   Exception2MessageMapper.extend_to(binding)
  58.   def_exception("ErrNoWaitingThread", "No threads for waiting.")
  59.   def_exception("ErrNoFinishedThread", "No finished threads.")
  60.   
  61.   #
  62.   # Waits until all specified threads have terminated.  If a block is provided,
  63.   # it is executed for each thread termination.
  64.   #
  65.   def ThreadsWait.all_waits(*threads) # :yield: thread
  66.     tw = ThreadsWait.new(*threads)
  67.     if block_given?
  68.       tw.all_waits do |th|
  69.     yield th
  70.       end
  71.     else
  72.       tw.all_waits
  73.     end
  74.   end
  75.   
  76.   #
  77.   # Creates a ThreadsWait object, specifying the threads to wait on.
  78.   # Non-blocking.
  79.   #
  80.   def initialize(*threads)
  81.     @threads = []
  82.     @wait_queue = Queue.new
  83.     join_nowait(*threads) unless threads.empty?
  84.   end
  85.   
  86.   # Returns the array of threads in the wait queue.
  87.   attr :threads
  88.   
  89.   #
  90.   # Returns +true+ if there are no threads to be synchronized.
  91.   #
  92.   def empty?
  93.     @threads.empty?
  94.   end
  95.   
  96.   #
  97.   # Returns +true+ if any thread has terminated.
  98.   #
  99.   def finished?
  100.     !@wait_queue.empty?
  101.   end
  102.   
  103.   #
  104.   # Waits for specified threads to terminate, and returns when one of
  105.   # the threads terminated.
  106.   #
  107.   def join(*threads)
  108.     join_nowait(*threads)
  109.     next_wait
  110.   end
  111.   
  112.   #
  113.   # Specifies the threads that this object will wait for, but does not actually
  114.   # wait.
  115.   #
  116.   def join_nowait(*threads)
  117.     threads.flatten!
  118.     @threads.concat threads
  119.     for th in threads
  120.       Thread.start(th) do |t|
  121.     begin
  122.       t.join
  123.     ensure
  124.       @wait_queue.push t
  125.     end
  126.       end
  127.     end
  128.   end
  129.   
  130.   #
  131.   # Waits until any of the specified threads has terminated, and returns the one
  132.   # that does.
  133.   #
  134.   # If there is no thread to wait, raises +ErrNoWaitingThread+.  If +nonblock+
  135.   # is true, and there is no terminated thread, raises +ErrNoFinishedThread+.
  136.   #
  137.   def next_wait(nonblock = nil)
  138.     ThreadsWait.fail ErrNoWaitingThread if @threads.empty?
  139.     begin
  140.       @threads.delete(th = @wait_queue.pop(nonblock))
  141.       th
  142.     rescue ThreadError
  143.       ThreadsWait.fail ErrNoFinishedThread
  144.     end
  145.   end
  146.   
  147.   #
  148.   # Waits until all of the specified threads are terminated.  If a block is
  149.   # supplied for the method, it is executed for each thread termination.
  150.   #
  151.   # Raises exceptions in the same manner as +next_wait+.
  152.   #
  153.   def all_waits
  154.     until @threads.empty?
  155.       th = next_wait
  156.       yield th if block_given?
  157.     end
  158.   end
  159. end
  160.  
  161. ThWait = ThreadsWait
  162.  
  163.  
  164. # Documentation comments:
  165. #  - Source of documentation is evenly split between Nutshell, existing
  166. #    comments, and my own rephrasing.
  167. #  - I'm not particularly confident that the comments are all exactly correct.
  168. #  - The history, etc., up the top appears in the RDoc output.  Perhaps it would
  169. #    be better to direct that not to appear, and put something else there
  170. #    instead.
  171.